<!DOCTYPE html>
<html>
  
<head><meta name="generator" content="Hexo 3.8.0">
  <meta charset="utf-8">
  <meta name="author" content="Amos Zhu">
  
  
  <title>Redis场景应用实例 | Amos的技术博客</title>

  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  
    <meta name="keywords" content="redis,redis,">
  

  
  <meta name="description" content="Redis的相关知识点和需要注意的问题我们都已经梳理过了，关键还是需要运用到实际的工作中才能达到学以致用，下面我们将整理一个实际应用的场景，并且集合Redis来实现其需求。">

  

  
    <script src="//cdn.jsdelivr.net/npm/leancloud-storage@3.11.1/dist/av-min.js" async></script>
  

  
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/MathJax.js?config=TeX-MML-AM_CHTML" async></script>
  

  
    <script src="//unpkg.com/valine/dist/Valine.min.js" async></script>
  

  

  <script>
  // theme-ad's config script
  // it can be used in every script
  
  window.AD_CONFIG = {
    leancloud: {"appid":"eObxCkTJ6j4GzRxGLgiHyfJa-gzGzoHsz","appkey":"fzRMAFC6MCE11mp7mnvh4Kwe","comment":true,"count":true},
    welcome: {"enable":true,"interval":30},
    start_time: "2019-05-28",
    passwords: ["efe07af7441da2b69c4a41e42e73be4db47f66010a56900788a458354a7373ec", ],
    is_post: true,
    lock: false,
    author: "Amos Zhu",
    share: {"qq":true,"wechat":true},
    mathjax: true,
    page_type: "",
    root: "/blog/"
  };
</script>

  <script src="/blog/vendor/sha256.min.js"></script>
<script src="/blog/js/auth.js"></script>
<script src="/blog/js/index.js"></script>
<script src="/blog/vendor/qrcode.min.js"></script>

  
    <link rel="icon" href="/blog/images/favicon.ico">
    <link rel="apple-touch-icon" href="/blog/images/touch-icon.png">
  

  <link href="//netdna.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet">

  <link rel="stylesheet" href="/blog/css/index.css">
<link rel="stylesheet" href="/blog/styles/components/highlight/highlight.css">

  
</head>
  <body>
    <header class="site-header">
  <div class="site-header-brand">
    
      <span class="site-header-brand-title">
        <a href="/blog/">Amos Zhu</a>
      </span>
    
    
      <span class="site-header-brand-motto"> | 当浮躁的心静不下，不妨写些东西或者看会书</span>
    
  </div>
  <div class="site-header-right">
    <nav class="site-header-navigation">
      
        <a href="/blog/" target="_self">首页</a>
      
        <a href="/blog/archives/" target="_self">归档</a>
      
        <a href="/blog/tags/" target="_self">标签</a>
      
        <a href="/blog/categories/" target="_self">分类</a>
      
        <a href="/blog/redis/" target="_self">redis</a>
      
        <a href="/blog/rabbitMQ/" target="_self">rabbitMQ</a>
      
        <a href="/blog/elasticsearch" target="_self">elasticsearch</a>
      
        <a href="/blog/stuff" target="_self">stuff</a>
      
        <a href="/blog/kafka" target="_self">kafka</a>
      
        <a href="/blog/friends/" target="_self">友链</a>
      
        <a href="/blog/about/" target="_self">关于</a>
      
    </nav>
    <div class="site-header-btn">
      
        <a href="https://gitee.com/amos_zhu" target="_blank" id="site-github">
          <i class="fa fa-github-alt"></i>
        </a>
      
      <a href="javascript:void(0);" id="site-search">
        <i class="fa fa-search"></i>
      </a>
      <a href="javascript:void(0);" id="site-nav-btn">
        <i class="fa fa-ellipsis-v"></i>
      </a>
    </div>
  </div>
</header>
<nav class="table-content" id="site-nav">
  <div class="table-content-title">
    <span>导航</span>
  </div>
  <div class="table-content-main">
    <ol class="toc">
      
        <li class="toc-item">
          <a href="/blog/" target="_self">
            首页
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/archives/" target="_self">
            归档
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/tags/" target="_self">
            标签
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/categories/" target="_self">
            分类
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/redis/" target="_self">
            redis
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/rabbitMQ/" target="_self">
            rabbitMQ
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/elasticsearch" target="_self">
            elasticsearch
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/stuff" target="_self">
            stuff
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/kafka" target="_self">
            kafka
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/friends/" target="_self">
            友链
          </a>
        </li>
      
        <li class="toc-item">
          <a href="/blog/about/" target="_self">
            关于
          </a>
        </li>
      
    </ol>
  </div>
</nav>
<div id="site-process"></div>
    <main>
      
  <div class="passage">
  <div class="passage-meta">
    <span>
      <i class="fa fa-calendar"></i>2019-06-22
    </span>
    
      <span>
        | <a href="/blog/categories/redis/"><i class="fa fa-bookmark"></i>redis</a>
      </span>
    
    
      <span>
        | <i class="fa fa-unlock-alt"></i>UNLOCK
      </span>
    
  </div>
  <h1 class="passage-title">
    Redis场景应用实例
  </h1>
  
  <article class="passage-article">
    <br><strong>目前公司有十万员工，分成500个部门，公司为员工制定了每日9点前和18点后网上签到的制度，签到之后可以及时查看自身签到状态，主管可以及时收到下属员工的签到状态，一整天未签到的员工自动补充旷工</strong><p></p>
<p><strong>以上为场景；请用java+redis+队列+mysql实现此功能</strong></p>
<blockquote>
<p>分析该需求，首先10w的员工签到，这个涉及到高并发的场景，并且主管还需要及时收到下属员工的签到状态，这个需要异步通知的功能，并且一整天未签到的员工自动补充旷工，这个需要一个定时任务来实现</p>
</blockquote>
<p>综上所述我们为了实现其功能最少需要高并发签到，异步通知以及定时任务这三个技能，明白了其所需要使用到的技术，下面我们来一个个的剖析，并且实现这样的功能。</p>
<h2 id="高并发来实现签到功能"><a href="#高并发来实现签到功能" class="headerlink" title="高并发来实现签到功能"></a>高并发来实现签到功能</h2><p>为了实现高并发，题目中已经给出了我们需要使用redis来实现，这个没得选，但是我们还是需要分析下是单机版还是Redis集群来实现这样的功能。</p>
<h3 id="单机还是集群？"><a href="#单机还是集群？" class="headerlink" title="单机还是集群？"></a>单机还是集群？</h3><p>10w员工，按照二八定律分析来说大概同时有2w的签到，也就是写请求（二八定律真乃神定律，在现实生活中随处可见），单机版本的Redis大概能支持10w左右的QPS（这个数值有波动，主要跟服务器的性能有关系，内存读写速度快的，这个数值还会更大点），所以我们这个单机版的Redis就能实现这样的功能，如果是员工是100w的话，我们就需要搭建Redis服务集群，最好还是能做到读写分离，这样还能做到横向扩容。</p>
<h3 id="数据结构很重要！！"><a href="#数据结构很重要！！" class="headerlink" title="数据结构很重要！！"></a>数据结构很重要！！</h3><p>一个适用的数据结构能优化代码逻辑，并且减少操作时间复杂度，优化服务响应速率，提升客户使用度，所以数据结构十分的重要。</p>
<ol>
<li>首先确定使用redis的数据类型</li>
</ol>
<p>学过Java的朋友应该都知道Java中的Map的理想操作时间复杂度是O(1),也就是说对于内存来说，访问任何地址的时间是一样的，即时间极短，相当于可以同时访问到所有地址，那么这里redis的hash数据类型和Java的Map是类似的，所以我们选用hash类型来实现所有员工在Redis中的数据存储</p>
<ol start="2">
<li>继续优化hash的数据结构</li>
</ol>
<p>看到这里有的朋友可能会考虑，将10w的员工的信息都存放在Redis中，就需要10w个key(map)，No,No,不是这样的！为什么不这样，我们来分析下。</p>
<p>还是跟Map的类型有关,如果10w个map存储在redis中，需要消耗一定的内存，并且数据越大，内存查询的速度也就越慢，所以我们的着眼点应该是按照部门来分别存储，这样查询的时候也可以根据部门来减少查询到次数，所以我们第一层的数据结构应该是以部门ID+常量+签到日期为key的map，这样做的好处有两个：</p>
<ul>
<li>每个人都是归属部门的，所以先根据部门来缩小查找的范围，减少查询遍历的次数：500+2000=2500,也就是说我们定位一个人最大遍历2500次就够了，而如果是直接查询个人的话，最大可能遍历10w次。</li>
<li>Redis中存放500个map比存放10w个map来的小的多，减少了redis的数据存储内存的消耗</li>
</ul>
<p>接着，我们再来分析下value的存储什么？</p>
<p>我们的需求是员工进行签到，所以我们的value值中必须要包含是否签到的相关信息，这里我们还可以扩展下，需求要求是上班前和下班后都进行签到，需要区分签到的类型，所以我们还可以添加一个常量来进行签到类型区分，其次是谁签到的，说到这里，我想这个数据结构已经很清晰了。</p>
<p><strong>是的还是使用hash结构来存放人员的信息，其中key值最好是人员的id，而value值可以是签到的状态</strong></p>
<ol start="3">
<li>数据结构的确定<br>至此，经过我们的分析，我们确定了Redis中签到的数据结构,使用Java的数据结构来表达：<figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 外围的Key是String类型： 主要存放部门的id+常量+签到日期</span></span><br><span class="line"><span class="comment">// 外围的Value是Map类型：主要存放该部门的人员的信息</span></span><br><span class="line"><span class="comment">// 里层的Key是String类型： 主要存放人员的ID</span></span><br><span class="line"><span class="comment">// 里层的key也是String类型（这里也可以修改为List类型）： 主要存放签到的状态</span></span><br><span class="line">Map&lt;String,Map&lt;String,String&gt;&gt;</span><br></pre></td></tr></table></figure>
</li>
</ol>
<h3 id="业务流程的实现"><a href="#业务流程的实现" class="headerlink" title="业务流程的实现"></a>业务流程的实现</h3><ol>
<li>初始化数据</li>
</ol>
<p>既然签到的map数据结构已经确定了，那么我们该怎么来使用这个数据结构来实现我们的业务呢？</p>
<p>这里提供一个方案，我们可以提前将部门的map的数据给初始化，有两个原因：</p>
<ul>
<li>部门和人员的数据一般变动不大，所以可以先初始化，节省时间，到时直接从Redis中取就可以了</li>
<li>避免签到的时候才来生成部门签到map，主要是为了避免签到高并发时，造成数据覆盖现象，导致签到数据不正确</li>
</ul>
<p>这里的部门签到map（暂时这么称呼），<strong>其有效期应该设置为永远，避免数据失效！</strong></p>
<ol start="2">
<li>签到</li>
</ol>
<p>用户登录系统后，我们会在redis中生成用户的基本信息，这里主要是用户的人员ID和所在部门的ID。</p>
<ul>
<li>用户签到的时候，将个人信息写入到redis,主要是为了用户查看其基本信息，包括签到的状态信息</li>
<li>根据员工ID和部门ID到部门签到map中获取人员的相关信息，并且更新签到状态。这里最好添加锁，防止被其他员工取到产生竞态，等部门签到map中的个人签到状态更新成功之后，释放锁，并且更新redis中个人信息中的签到状态</li>
<li>将签到相关信息放入队列中</li>
</ul>
<p>上述的签到流程操作，可以及时的让用户查看到自己的签到情况，即使高并发的情况下也不影响系统的响应流畅度</p>
<ol start="3">
<li>通知主管</li>
</ol>
<p>用户签到之后，就将签到的信息发送到队列，通过队列来异步通知主管，这里可以使用RabbitMQ来实现消息的发送通知，主要是考虑RabbitMQ的消息的安全和消息消费失败后，可以使用死信队列来实现重发，确保消息的准确和安全性。</p>
<ol start="4">
<li>定时数据持久化</li>
</ol>
<p>开启一个定时任务，将部门签到map提取出来，然后循环遍历，将人员签到的信息持久化到数据库，对于持久化失败的数据，可以写入到日志中，展示给相关人员查看。将一整天都未签到的人员置为旷工。</p>
<p><strong>数据持久化后，可以删除当天的部门签到map，同时初始化明天需要用到的部门签到map</strong></p>
<p>可以是用流程图展示如下：</p>
<p><img src="https://s2.ax1x.com/2019/06/22/Z9Mq0g.png" alt></p>
<p>至此，我们的整个业务流程就很清晰了，对应的代码实现也就很容易了</p>
<h2 id="总结"><a href="#总结" class="headerlink" title="总结"></a>总结</h2><p>在对人员签到的分析设计已经结束了，不过我们就其中的几个问题需要讨论下</p>
<h4 id="为了实现上述的功能，redis中最小的key值是多少？"><a href="#为了实现上述的功能，redis中最小的key值是多少？" class="headerlink" title="为了实现上述的功能，redis中最小的key值是多少？"></a>为了实现上述的功能，redis中最小的key值是多少？</h4><p>我们上面设计中 redis中的key是500个？ 那能不能再次缩小呢？ 其实是可以的，就是在外面再加一层map，这样保存到redis中就一个key键值了，如果这样设计的话，那其实没有什么意义，还是需要查找到对应的部门，再查找到人员，这样反而增加了一步查询，还不如不加，而且如果只有一个key值的话，那么用户签到的时候需要加锁，就将这个key添加了锁，这样话并发量就不是很大了，所有的用户都要等该用户签到完成后再进行其拿到，从业务角度来看就是将10w员工的签到串行了，我们上面设计的500个key，对不不同部门的人员签到是不影响的，从业务角度来说，不同部门是可以同时签到的，而且不影响数据，提高了效率。</p>
<h4 id="为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？"><a href="#为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？" class="headerlink" title="为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？"></a>为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？</h4><p>我们上面的设计中 redis的部门签到map中已经存放了人员的签到信息，为什么还要在个人信息中存放签到信息呢？ 主要是为了需求中用户可以随时查看自己的签到状态。</p>
<p>这里有的朋友可能就疑问了，部门签到map中不是已经存在了么，这里主要是为了人员查看的效率考虑的，如果存放在部门签到map中，那么每次查看一次都需要从部门签到map中提取出来个人信息才能查看，这样会影响查看效率。</p>
<h4 id="如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？"><a href="#如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？" class="headerlink" title="如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？"></a>如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？</h4><p>加锁的功能其实也可以由redis来实现，我们可以在签到时，对这个部门ID+加锁常量+签到日期，在redis中新增一个key，如果同部门的其他用户也来签到时，先查看是否存在部门ID+加锁常量+签到日期的key，如果存在则循环等待一段时间再请求，相当于给当前签到用户添加了锁，等这个用户签到成功后，再删除这个key。</p>
<p>上面就是简单的加锁的功能，这样需要考虑释放锁的问题，如果加锁成功了，程序在处理业务时程序异常，没有正常的释放锁，这样就会造成其他的人员获取不到锁，无法进行业务操作，解决这个问题，我们首先需要考虑不管业务是否成功，我们都需要释放锁，这样至少不会对其他的人员签到造成影响。</p>
<p>那么该如何实现这样能，其实redis能很简单的实现，就是给这个key添加失效时间，这样只要到失效时间，这个key就会被删除，也就相当于释放了锁。</p>
  </article>
  <aside class="table-content" id="site-toc">
  <div class="table-content-title">
    <i class="fa fa-arrow-right fa-lg" id="site-toc-hide-btn"></i>
    <span>目录</span>
  </div>
  <div class="table-content-main">
    <ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#高并发来实现签到功能"><span class="toc-text">高并发来实现签到功能</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#单机还是集群？"><span class="toc-text">单机还是集群？</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#数据结构很重要！！"><span class="toc-text">数据结构很重要！！</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#业务流程的实现"><span class="toc-text">业务流程的实现</span></a></li></ol></li><li class="toc-item toc-level-2"><a class="toc-link" href="#总结"><span class="toc-text">总结</span></a><ol class="toc-child"><li class="toc-item toc-level-4"><a class="toc-link" href="#为了实现上述的功能，redis中最小的key值是多少？"><span class="toc-text">为了实现上述的功能，redis中最小的key值是多少？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？"><span class="toc-text">为什么需要吧签到的信息发到员工的信息里，还要保存到部门签到map中？</span></a></li><li class="toc-item toc-level-4"><a class="toc-link" href="#如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？"><span class="toc-text">如果基于redis实现加锁和释放锁功能，如何考虑其中的锁释放问题？</span></a></li></ol></li></ol>
  </div>
</aside>
  
    <aside class="passage-copyright">
      <div>本文作者: Amos Zhu</div>
      
        <div>
          原文链接: 
          <a href target="_blank">http://amos_zhu.gitee.io/passages/Redis场景应用实例/</a>
        </div>
      
      <div>
        版权声明: 本博客所有文章除特别声明外, 均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a> 许可协议. 转载请注明出处!
      </div>
    </aside>
  
  
    <div class="passage-tags">
     
      <a href="/blog/tags/redis/"><i class="fa fa-tags"></i>redis</a>
    
    </div>
  
</div>

    </main>
    
      
<div class="site-comment-contanier" data-plateform="leancloud">
  
    <p id="site-comment-info">
      <i class="fa fa-spinner fa-spin"></i> 评论加载中
    </p>
    <div id="site-comment"></div>
  
</div>
    
    <div class="site-footer-wrapper">
  <footer class="site-footer">
    
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">博客推荐</h5>
          
            <span class="site-footer-item">
              <a href="http://youzhixueyuan.com/series/java" target="_blank">优知学院</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://ruanyifeng.com/" target="_blank">阮一峰的个人网站</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">系列教程</h5>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/redis" target="_blank">Redis系列教程</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/rabbitMQ/" target="_blank">RabbitMQ教程</a>
            </span>
          
            <span class="site-footer-item">
              <a href="http://amos_zhu.gitee.io/blog/kafka/" target="_blank">Kafka架构探险</a>
            </span>
          
        </div>
      
        <div class="site-footer-col">
          <h5 class="site-footer-title">抓到我</h5>
          
            <span class="site-footer-item">
              <a href="https://gitee.com/amos_zhu" target="_blank">Gitee</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://blog.csdn.net/wdcl2468" target="_blank">CSDN</a>
            </span>
          
            <span class="site-footer-item">
              <a href="https://www.jianshu.com/u/2dbe61b1f3c3" target="_blank">简书</a>
            </span>
          
        </div>
      
    
    <div class="site-footer-info">
      <i class="fa fa-clock-o"></i> 本站已稳定运行<span id="site-time"></span>
    </div>
    
      <div class="site-footer-info">
        <i class="fa fa-paw"></i> 您是本站第 <span id="site-count"></span> 位访客
      </div>
    
    
      <div class="site-footer-info">
        <i class="fa fa-at"></i> Email: amoszhu@aliyun.com
      </div>
    
    <div class="site-footer-info">
      <i class="fa fa-copyright"></i> 
      2019 <a href="https://github.com/dongyuanxin/theme-ad/" target="_blank">Theme-AD</a>.
      Created by <a href="https://godbmw.com/" target="_blank">GodBMW</a>.
      All rights reserved.
    </div>
  </footer>
</div>
    <div id="site-layer" style="display:none;">
  <div class="site-layer-content">
    <div class="site-layer-header">
      <span class="site-layer-header-title" id="site-layer-title"></span>
      <i class="fa fa-close" id="site-layer-close"></i>
    </div>
    <div class="site-layer-body" id="site-layer-container">
      <div class="site-layer-input" id="site-layer-search" style="display: none;">
        <div class="site-layer-input-choose">
          <a href="javascript:void(0);" title="Change Search Engine">Google</a>
        </div>
        <input type="text">
        <i class="fa fa-search"></i>
      </div>
      
        <div class="site-layer-reward" id="site-layer-reward" style="display: none;">
          
            <div>
              <img src="/blog/images/wechat.png" alt="WeChat">
              
                <p>WeChat</p>
              
            </div>
          
            <div>
              <img src="/blog/images/alipay.png" alt="AliPay">
              
                <p>AliPay</p>
              
            </div>
          
        </div>
      
      <div id="site-layer-welcome" style="display:none;"></div>
    </div>
  </div>
</div>
    

<div class="bottom-bar">
  <div class="bottom-bar-left">
    <a href="/blog/passages/Centos7下RabbitMQ的搭建/" data-enable="true">
      <i class="fa fa-arrow-left"></i>
    </a>
    <a href="/blog/passages/Redis面试以及在分布式集群环境中遇到的问题/" data-enable="true">
      <i class="fa fa-arrow-right"></i>
    </a>
  </div>
  <div class="bottom-bar-right">
    <a href="javascript:void(0);" data-enable="true" id="site-toc-show-btn">
      <i class="fa fa-bars"></i>
    </a>
    
      <a href="#site-comment" data-enable="true">
        <i class="fa fa-commenting"></i>
      </a>
    
    <a href="javascript:void(0);" id="site-toggle-share-btn">
      <i class="fa fa-share-alt"></i>
    </a>
    
      <a href="javascript:void(0);" id="site-reward">
        <i class="fa fa-thumbs-up"></i>
      </a>
    
    <a href="javascript:void(0);" id="back-top-btn">
      <i class="fa fa-chevron-up"></i>
    </a>
  </div>
</div>
    <div id="share-btn">
  
  
  
  
    <a id="share-btn-qq" href="javascript:void(0);" target="_blank">
      <i class="fa fa-qq"></i>
    </a>
  
  
    <a id="share-btn-wechat" href="javascript:void(0);" target="_blank">
      <i class="fa fa-wechat"></i>
    </a>
  
</div>
    


  <script async>
  (function(){
      var bp = document.createElement('script');
      var curProtocol = window.location.protocol.split(':')[0];
      if (curProtocol === 'https') {
          bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
      }
      else {
          bp.src = 'http://push.zhanzhang.baidu.com/push.js';
      }
      var s = document.getElementsByTagName("script")[0];
      s.parentNode.insertBefore(bp, s);
  })();
  </script>



  <script async>
    (function(){
    var src = (document.location.protocol == "http:") ? "http://js.passport.qihucdn.com/11.0.1.js?":"https://jspassport.ssl.qhimg.com/11.0.1.js?";
    document.write('<script src="' + src + '" id="sozz"><\/script>');
    })();
  </script>


    
  </body>
</html>